﻿//
//
//// 示例代码 3-1
//// 智能指针的部分模拟实现
//#include <iostream>
//#include <atomic>
//#include <cassert>
//#include <functional>
//using namespace std;
//
//struct Date
//{
//	Date(int year = 1970, int month = 1, int day = 1)
//		: _year(year)
//		, _month(month)
//		, _day(day)
//	{}
//
//	~Date()
//	{
//		cout << "~Date" << endl;
//		_year = 0;
//		_month = 0;
//		_day = 0;
//	}
//
//	int _year;
//	int _month;
//	int _day;
//};
//
//namespace yyp
//{
//	template <class T>
//	class auto_ptr
//	{
//	public:
//		explicit auto_ptr(T* ptr = nullptr)
//			: _ptr(ptr)
//		{}
//
//		// 管理权转移
//		auto_ptr(auto_ptr& ap)
//			: _ptr(ap._ptr)
//		{
//			ap._ptr = nullptr;
//		}
//
//		auto_ptr& operator=(auto_ptr& ap)
//		{
//			if (this != &ap)
//			{
//				if (_ptr)
//					delete _ptr;	// 释放当前对象中资源
//
//				_ptr = ap._ptr;		// 转移资源
//				ap._ptr = nullptr;
//			}
//
//			return *this;
//		}
//
//		T* get() const
//		{
//			return _ptr;
//		}
//
//		// 像指针⼀样使⽤
//		T& operator*() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return *_ptr;
//		}
//
//		T* operator->() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return _ptr;
//		}
//
//		~auto_ptr()
//		{
//			if (_ptr)
//			{
//				cout << "auto_ptr delete: " << _ptr << endl;
//				delete _ptr;
//				_ptr = nullptr;
//			}
//		}
//
//	private:
//		T* _ptr;
//	};
//
//	template <class T>
//	class unique_ptr
//	{
//	public:
//		explicit unique_ptr(T* ptr = nullptr)
//			: _ptr(ptr)
//		{}
//
//		unique_ptr(const unique_ptr& up) = delete;
//		unique_ptr operator=(const unique_ptr& up) = delete;
//
//		unique_ptr(unique_ptr&& up) noexcept
//			: _ptr(up._ptr)
//		{
//			up._ptr = nullptr;
//		}
//
//		unique_ptr& operator=(unique_ptr&& up)
//		{
//			if (_ptr)
//				delete _ptr;
//
//			_ptr = up._ptr;
//			up._ptr = nullptr;
//
//			return *this;
//		}
//
//		T* get() const
//		{
//			return _ptr;
//		}
//
//		// 像指针⼀样使⽤
//		T& operator*() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return *_ptr;
//		}
//
//		T* operator->() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return _ptr;
//		}
//
//		~unique_ptr()
//		{
//			if (_ptr)
//			{
//				cout << "unique_ptr delete: " << _ptr << endl;
//				delete _ptr;
//				_ptr = nullptr;
//			}
//		}
//
//	private:
//		T* _ptr;
//	};
//
//	template <class T>
//	class shared_ptr
//	{
//	public:
//		explicit shared_ptr(T* ptr = nullptr)
//			: _ptr(ptr)
//			, _pcount(new atomic<int>(1))
//		{}
//
//		// 1、类模板与成员函数模板的同名模板参数（如均用T）会因作用域嵌套发生名称遮蔽，编译器会将其识别为两个完全独立的类型参数
//		// 建议使用不同命名，显式指明这两个模板参数可以是不同类型
//		// 实例化的模板函数中，二者的实际类型要么相同，要么是（类模板）基类和（成员函数模板）派生类的关系，都可以执行_ptr(ptr)的赋值操作
//		// 2、可以将模板参数简化为一个。此时可以直接使用类模板的T参数 template <class D>
//		//template <class T, class D>
//		template <class U, class D>
//		shared_ptr(U* ptr, D del)
//			: _ptr(ptr)
//			, _pcount(new atomic<int>(1))
//			, _del(del)
//		{}
//
//		shared_ptr(const shared_ptr& sp)
//			: _ptr(sp._ptr)
//			, _pcount(sp._pcount)
//			, _del(sp._del)
//		{
//			++(*_pcount);
//		}
//
//		shared_ptr(shared_ptr&& sp)
//		{
//			_ptr = sp._ptr;
//			_pcount = sp._pcount;
//			_del = sp._del;
//
//			sp._ptr = nullptr;
//			sp._pcount = nullptr;
//		}
//
//		shared_ptr& operator=(const shared_ptr& sp)
//		{
//			//if (this != &sp)
//			if (_ptr != sp._ptr)
//			{
//				release();
//
//				_ptr = sp._ptr;
//				_pcount = sp._pcount;
//				++(*_pcount);
//				_del = sp._del;
//			}
//
//			return *this;
//		}
//
//		shared_ptr& operator=(shared_ptr&& sp)
//		{
//			if (_ptr != sp._ptr)
//			{
//				release();
//
//				_ptr = sp._ptr;
//				_pcount = sp._pcount;
//				++(*_pcount);
//				_del = move(sp._del); // 移动删除器（function支持移动，更高效）
//			}
//
//			return *this;
//		}
//
//		void release()
//		{
//			if (_pcount && 0 == --(*_pcount))
//			{
//				// 最后⼀个管理资源的对象析构时，释放其管理的资源
//				_del(_ptr);
//				delete _pcount;
//				_ptr = nullptr;
//				_pcount = nullptr;
//			}
//		}
//
//		T& operator*() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return *_ptr;
//		}
//
//		T* operator->() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return _ptr;
//		}
//
//		int use_count() const
//		{
//			// 返回0仅表示不持有资源的空实例
//			return _pcount ? _pcount->load() : 0;
//
//			//return *_pcount;			// atomic<int> 到 int 的转换
//			//return _pcount->load();	// 返回存储的int值
//		}
//
//		T* get() const
//		{
//			return _ptr;
//		}
//
//		~shared_ptr()
//		{
//			cout << "shared_ptr delete: ";
//			if (!_ptr)
//			{
//				cout << "空对象";
//			}
//			else
//			{
//				cout << "引用计数 " << (_pcount ? _pcount->load() : 0);
//				if (_pcount && 1 == _pcount->load())
//					cout << " ，释放管理的资源 " << _ptr;
//			}
//			cout << endl;
//
//			release();
//		}
//
//	private:
//		T* _ptr;
//		//int* _pcount;
//		atomic<int>* _pcount;	// 原子类型，线程安全
//
//		function<void(T*)> _del = [](T* ptr) {
//			delete ptr;
//			ptr = nullptr;
//		};
//	};
//
//	// 这里的shared_ptr和weak_ptr都是以最简洁的⽅式实现只能满⾜基本的功能
//	// weak_ptr的lock等功能这里⽆法实现，想要实现就要同时修改shared_ptr和weak_ptr
//	// 把引⽤计数取出设计为⼀个单独的类，shared_ptr和weak_ptr都要存储指向这个类的对象
//	// 有兴趣可以翻翻源代码
//	template <class T>
//	class weak_ptr
//	{
//	public:
//		weak_ptr()
//		{}
//
//		weak_ptr(const shared_ptr<T>& sp)
//			: _ptr(sp.get())
//		{}
//
//		weak_ptr& operator=(const shared_ptr<T>& sp)
//		{
//			_ptr = sp.get();
//
//			return *this;
//		}
//
//	private:
//		T* _ptr = nullptr;
//	};
//
//	void Test4()
//	{
//		auto_ptr<Date> ap1(new Date);
//		auto_ptr<Date> ap2(ap1);		// ap1被悬空
//
//		//ap1->_year;					// 空指针访问，ap1已悬空
//
//		unique_ptr<Date> up1(new Date);
//		//unique_ptr<Date> up2(up1);	// 不支持拷贝
//		unique_ptr<Date> up3(move(up1));// 支持移动
//
//		shared_ptr<Date> sp1(new Date);
//		shared_ptr<Date> sp2(sp1);		// 支持拷贝
//		shared_ptr<Date> sp3(sp2);		// sp1、sp2、sp3管理同一个资源
//
//		cout << "auto_ptr  : " << ap1.get() << "\t" << ap2.get() << endl;
//		cout << "unique_ptr: " << up1.get() << "\t" << up3.get() << endl;
//		cout << "shared_ptr: " << sp1.get() << "\t" << sp2.get() << "\t" << sp3.get() << endl << endl;
//
//		cout << sp1.use_count() << "\t" << sp2.use_count() << "\t" << sp3.use_count() << endl << endl;
//
//		cout << sp1->_year << "\t" << sp2->_year << "\t" << sp3->_year << endl;
//		++sp3->_year;
//		cout << sp1->_year << "\t" << sp2->_year << "\t" << sp3->_year << endl << endl;
//
//		shared_ptr<Date> sp4(move(sp1));// ⽀持移动
//		cout << sp4.use_count() << endl << endl;
//	}
//
//}
//
//int main()
//{
//	yyp::Test4();
//
//	return 0;
//}


// 示例代码 4-3
// 线程安全的shared_ptr
//#include <iostream>
//#include <atomic>
//#include <mutex>
//#include <thread>
//#include <cassert>
//#include <functional>
//using namespace std;
//
//namespace yyp
//{
//	template <class T>
//	class shared_ptr
//	{
//	public:
//		explicit shared_ptr(T* ptr = nullptr)
//			: _ptr(ptr)
//			, _pcount(new atomic<int>(1))
//		{}
//
//		template <class U, class D>
//		shared_ptr(U* ptr, D del)
//			: _ptr(ptr)
//			, _pcount(new atomic<int>(1))
//			, _del(del)
//		{}
//
//		shared_ptr(const shared_ptr& sp)
//		{
//			std::unique_lock<std::mutex> lk(_mtx);
//
//			// 避免sp被并发修改
//			_ptr = sp._ptr;
//			_pcount = sp._pcount;
//			_del = sp._del;
//
//			if (_pcount)
//				++(*_pcount);
//		}
//
//		shared_ptr(shared_ptr&& sp)
//		{
//			std::unique_lock<std::mutex> lk(_mtx);
//
//			_ptr = sp._ptr;
//			_pcount = sp._pcount;
//			_del = sp._del;
//
//			sp._ptr = nullptr;
//			sp._pcount = nullptr;
//			sp._del = nullptr;
//		}
//
//		shared_ptr& operator=(const shared_ptr& sp)
//		{
//			std::unique_lock<std::mutex> lk(_mtx);
//
//			//if (this != &sp)
//			if (_ptr != sp._ptr)
//			{
//				release();
//
//				_ptr = sp._ptr;
//				_pcount = sp._pcount;
//				++(*_pcount);
//				_del = sp._del;
//			}
//
//			return *this;
//		}
//
//		shared_ptr& operator=(shared_ptr&& sp)
//		{
//			std::unique_lock<std::mutex> lk(_mtx);
//
//			if (_ptr != sp._ptr)
//			{
//				release();
//
//				_ptr = sp._ptr;
//				_pcount = sp._pcount;
//				++(*_pcount);
//				_del = move(sp._del); // 移动删除器（function支持移动，更高效）
//			}
//
//			return *this;
//		}
//
//		void release()
//		{
//			if (_pcount && 0 == --(*_pcount))
//			{
//				// 最后⼀个管理资源的对象析构时，释放其管理的资源
//				_del(_ptr);
//				delete _pcount;
//				_ptr = nullptr;
//				_pcount = nullptr;
//			}
//		}
//
//		T& operator*() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return *_ptr;
//		}
//
//		T* operator->() const
//		{
//			if (!_ptr)
//				assert(false);
//
//			return _ptr;
//		}
//
//		int use_count() const
//		{
//			return _pcount ? _pcount->load() : 0;
//		}
//
//		T* get() const
//		{
//			return _ptr;
//		}
//
//		~shared_ptr()
//		{
//			std::unique_lock<std::mutex> lk(_mtx);	// 提前加锁，确保计数读取和释放的原子性
//
//			int cur_count = _pcount->load();
//			cout << "shared_ptr delete: ";
//			if (nullptr == _ptr)
//			{
//				cout << "空对象";
//			}
//			else
//			{
//				cout << "引用计数 " << cur_count;
//				if (1 == cur_count)
//					cout << " ，释放管理的资源 " << _ptr;
//			}
//			cout << endl;
//
//			release();
//		}
//
//	private:
//		T* _ptr;
//		atomic<int>* _pcount;
//		static mutex _mtx;
//
//		function<void(T*)> _del = [](T* ptr) {
//			delete ptr;
//			ptr = nullptr;
//		};
//	};
//	template <class T>
//	mutex shared_ptr<T>::_mtx;
//}
//
//void Test7()
//{
//	struct A
//	{
//		int _a = 0;
//		int _b = 0;
//
//		~A()
//		{
//			cout << "~A" << endl;
//		}
//	};
//
//	mutex Mutex;
//	const size_t N = 3;
//	yyp::shared_ptr<A> sp(new A());
//
//	/*auto f = [&]
//	{
//		for (size_t i = 0; i < N; ++i)
//		{
//			yyp::shared_ptr<A> copy(sp);
//
//			{
//				unique_lock<mutex> lk(Mutex);
//				++copy->_a;
//				++copy->_b;
//			}
//		}
//	};
//
//	thread t1(f);
//	thread t2(f);*/
//
//	auto f = [&](int thread_id) {  // 传入线程 ID 便于区分
//		for (size_t i = 0; i < N; ++i) {
//			yyp::shared_ptr<A> copy(sp);
//			{
//				unique_lock<mutex> lk(Mutex);
//				++copy->_a;
//				++copy->_b;
//
//				cout << "线程 " << thread_id << " 第 " << i + 1 << " 次循环，当前 _a=" << copy->_a << ", b=" << copy->_b << endl;
//			}
//		}
//	};
//
//	thread t1(f, 1);  // 线程 1
//	thread t2(f, 2);  // 线程 2
//
//	t1.join();
//	t2.join();
//
//	cout << "\n************" << endl;
//	cout << sp.use_count() << endl;
//	cout << sp->_a << " " << sp->_b << endl;
//	cout << "************" << endl << endl;
//}
//
//int main()
//{
//	Test7();
//
//	return 0;
//}


#include <iostream>
#include <memory>
using namespace std;

struct Date
{
	Date(int year = 1970, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	~Date()
	{
		cout << "~Date" << endl;
		_year = 0;
		_month = 0;
		_day = 0;
	}

	int _year;
	int _month;
	int _day;
};

int main()
{
	shared_ptr<Date[]> sp1(new Date[10]);
	shared_ptr<Date[]> sp2(new Date[10], default_delete<Date[]>());

	return 0;
}